﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Lab2___Mineria_de_datos.Modelo;

namespace Lab2___Mineria_de_datos.Infraestructura
{
    public class Lector : IDisposable
    {
        private StreamReader fileStream;
        private TipoArchivoEntrada tipoArchivo;
        private Entities db;

        public Lector(String filePath, TipoArchivoEntrada tipo)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException();
            }

            String ext = Path.GetExtension(filePath);
            if (ext.Equals(".names"))
            {
                if (tipo != TipoArchivoEntrada.Names)
                {
                    throw new ExtensionDelArchivoNoCoincideException();
                }
            }
            else if (ext.Equals(".data"))
            {
                if (tipo != TipoArchivoEntrada.Data)
                {
                    throw new ExtensionDelArchivoNoCoincideException();
                }
            }
            else
            {
                throw new FileLoadException();
            }

            tipoArchivo = tipo;
            fileStream = new StreamReader(filePath);
            db = new Entities();
        }

        public void getDatos()
        {
            switch (tipoArchivo)
            {
                case TipoArchivoEntrada.Names:
                    getDatosFromNames();
                    break;
                case TipoArchivoEntrada.Data:
                    getDatosFromData();
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }

        private void getDatosFromData()
        {
            int i = 1;
            while (!fileStream.EndOfStream)
            {
                TUPLA tupla = new TUPLA
                {
                    NUMERO_TUPLA = i
                };

                string[] tup = fileStream.ReadLine().Split(',');
                int j = 0;
                foreach (string med in tup)
                {
                    if (j == tup.Length-1)
                    {
                        tupla.CLASE = db.CLASE.ToArray().First(c => c.NOMBRE_CLASE.Equals(med.Trim()));
                        //db.SaveChanges();
                        break;
                    }

                    ATRIBUTO atributo = db.ATRIBUTO.ToArray()[j];
                    int rang = int.Parse(med);
                    tupla.MEDICION.Add(new MEDICION
                        {
                            ATRIBUTO = atributo,
                            RANGO = db.RANGO.First(r => r.ID_ATRIBUTO == atributo.ID_ATRIBUTO
                                                     && r.IDENTIFICADOR == rang)
                            //ID_RANGO = int.Parse(med)
                        });
                    j++;
                    
                    //db.SaveChanges();
                }
                //db.TUPLA.Add(tupla);
                db.AddObject("TUPLA", tupla);
                db.SaveChanges();
                i++;
            }
        }

        private void getDatosFromNames()
        {
            int i = 1;
            foreach (string clase in fileStream.ReadLine().Split(','))
            {
                CLASE c = new CLASE
                {
                    ID_CLASE = i,
                    NOMBRE_CLASE = clase.Trim()
                };
                db.AddObject("CLASE", c);
                i++;
            }
            db.SaveChanges();

            int j = 1;
            int k = 1;
            while (!fileStream.EndOfStream)
            {
                string atrib = fileStream.ReadLine();
                string rangos = atrib.Split(':').ToArray()[1];

                ATRIBUTO atributo = new ATRIBUTO
                {
                    ID_ATRIBUTO = j,
                    NOMBRE_ATRIBUTO = atrib.Split(':').ToArray()[0]
                };
                
                //db.SaveChanges();
                j++;

                foreach (string rango in rangos.Split(','))
                {
                    atributo.RANGO.Add(new RANGO
                    {
                        ID_RANGO = k,
                        IDENTIFICADOR = int.Parse(rango)
                    });
                    k++;
                }
                db.AddObject("ATRIBUTO", atributo);
                //db.A
                //db.ATRIBUTO.Add(atributo);
                db.SaveChanges();
            }
        }

        public void Dispose()
        {
            if (fileStream != null)
            {
                fileStream.Close();
            }

            if (db != null)
            {
                db.Dispose();
            }
        }
    }

    public enum TipoArchivoEntrada
    {
        Names,
        Data
    }
}
